﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Security.Cryptography;

using TTServer.Utilities;
using libAsymmetricEncryption;
using libUtilities;
//using libSecuritySystem;
using bmttPPTController.TTServer;
using ThresholdModeling;

namespace TTServer
{
    public partial class FormTTServerGUI : Form
    {
        public FormTTServerGUI()
        {
            InitializeComponent();
        }

        private SocketServer m_socketServer = null;
        private BluetoothServer m_bluetoothServer = null;
        private AuthenManagement _authenManager = null;
        private List<MembersGroup> _groups = new List<MembersGroup>();

        private void TTServerGUI_Load(object sender, EventArgs e)
        {
            
            RSA_KeyManager keyManager = RSA_KeyManager.getInstance();
            keyManager.initServerKeys();

            //TestRSA();

            string serverIP = OtherUtils.GetServerIP("ipv4");
            Global.serverIP = serverIP;

            txtServerIP.Text = Global.serverIP;
            txtPort.Text = Global.port.ToString();

            //txtCurrentN.Text = Global.n.ToString();
            //txtCurrentK.Text = Global.k.ToString();

            btnShutdownLANServer.Enabled = false;
            btnShutdownBluetoothServer.Enabled = false;

            OnStartLANServer();

            //OnStartBluetoothServer();

            TryInitAuthenManagement();

            DrawingScreenManager.GetInstance().Init();
            DrawingScreenManager.GetInstance().ShowDrawingScreen();
            DrawingScreenManager.GetInstance().HideDrawingScreen();

            this._authenManager = AuthenManagement.getInstance();
            //this._authenManager.ConstructThresholdPattern();

            //gbLanServer.Enabled = false;
            //gbBluetoothServer.Enabled = false;

            ////////////////////////////////////////////////////////////////////
            // Tam thoi tat di
            
            bool cdb = TMUtils.InitDatabase();
            if (cdb)
                MessageBox.Show("Database initialize successfully!", "Notify");
            else
                MessageBox.Show("Database initialize fail!", "Error");
             

            //Authen group
            LoadGroupToCombobox();
            btLogoutGroup.Enabled = false;
            this._authenManager.AuthenType = 1;
            rbType1.Checked = true;
        }

        public void TestRSA()
        {
            RSA_KeyManager rsa_key_manager = RSA_KeyManager.getInstance();

            RSA_Key serverPublicKey = rsa_key_manager.ServerPublicKey;

            RSAParameters privateParameters = rsa_key_manager.privateParameters;

            byte[] dataToEncrypt = { 1, 2, 3, 4, 5, 6, 7 , 23, 56};

            byte[] encryptedData = RSA_Algorithm.rsaEncryptWithPublicKey(serverPublicKey, dataToEncrypt);

            byte[] decryptedData = RSA_Algorithm.rsaDecryptWithPrivateKey(privateParameters, encryptedData);

            byte[] temp = decryptedData;
        }

        private void btnRandomNewPort_Click(object sender, EventArgs e)
        {
            int port = OtherUtils.GetANewPort();

            while (port == Global.port)
            {
                port = OtherUtils.GetANewPort();
            }

            Global.port = port;

            txtPort.Text = port.ToString();
        }

        private void OnStartLANServer()
        {
            try
            {
                m_socketServer = new SocketServer();

                if (m_socketServer != null)
                {
                    m_socketServer.Start();

                    btnStartLANServer.Enabled = false;
                    btnShutdownLANServer.Enabled = true;

                    // Tam thoi duoc tat di
                    //MessageBox.Show("Lan Server is started!", "Notify");
                    //lbLanServerWaiting.Text = "Waiting for Clients...";
                }
                else
                {
                    throw new Exception();
                }
            }
            catch
            {
                MessageBox.Show("Start the LAN server unsuccessfully.");
            }
        }

        private void OnStartBluetoothServer()
        {
            try
            {
                m_bluetoothServer = new BluetoothServer();

                if (m_bluetoothServer != null)
                {
                    m_bluetoothServer.StartBluetooth();

                    if (m_bluetoothServer.NotSupported)
                    {
                        btnStartBluetoothServer.Enabled = false;
                        btnShutdownBluetoothServer.Enabled = false;

                        MessageBox.Show("Bluetooth not supported");
                    }
                    else
                    {
                        //MessageBox.Show("Bluetooth supported");

                        btnStartBluetoothServer.Enabled = false;
                        btnShutdownBluetoothServer.Enabled = true;
                    }
                }
                else
                {
                    throw new Exception();
                }
            }
            catch
            {
                MessageBox.Show("Start the bluetooth server unsuccessfully.");
            }

        }

        private void TryInitAuthenManagement()
        {
            //try
            //{
            //    if (AuthenManagement.getInstance().isAvailable() == false)
            //    {
            //        AuthenManagement.getInstance().NMemberSystem = new NMembersSystem(5, 2, 10);
            //    }
            //}
            //catch
            //{
            //    MessageBox.Show("Cannot initialize the N Member System with current parameters.");
            //}
        }


        private void btnStartServer_Click(object sender, EventArgs e)
        {
            this.OnStartLANServer();
        }

        private void btnShutdownServer_Click(object sender, EventArgs e)
        {
            try
            {
                if (m_socketServer != null)
                {
                    m_socketServer.Terminate();

                    btnStartLANServer.Enabled = true;
                    btnShutdownLANServer.Enabled = false;
                    MessageBox.Show("Lan Server stopped. Press Start Lan Server to start it again!", "Notify");
                    lbLanServerWaiting.Text = "";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unsuccessful");
            }
        }

        private void btnStartBluetoothServer_Click(object sender, EventArgs e)
        {
            OnStartBluetoothServer();
        }

        private void btnShutdownBluetoothServer_Click(object sender, EventArgs e)
        {

            try
            {
                if (m_bluetoothServer != null)
                {
                    m_bluetoothServer.StopBluetooth();
                    btnStartBluetoothServer.Enabled = true;
                    btnShutdownBluetoothServer.Enabled = false;
                }
                else
                {
                    throw new Exception();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unsuccessful");
            }
        }

        private void TTServerGUI_FormClosing(object sender, FormClosingEventArgs e)
        {
            SaveSetingsToFile();

            // Shutdown all server

            if (m_socketServer != null)
            {
                m_socketServer.Terminate();
            }

            if (m_bluetoothServer != null)
            {
                m_bluetoothServer.StopBluetooth();
            }

            DrawingScreenManager.GetInstance().HideTrayIcon();
        }

        private void btnSetAnotherPort_Click(object sender, EventArgs e)
        {
            Form form = new FormSetPort(this);
            form.ShowDialog();
        }

        public void SetPort(int port)
        {
            Global.port = port;

            txtPort.Text = port.ToString();
        }

        public void SetAdministratorPassword(String password)
        {
            Global.admistratorPassword = password;
        }



        private void btnSetAnotherAdminPassword_Click(object sender, EventArgs e)
        {
            Form form = new FormSetAdminPassword(this);
            form.ShowDialog();
        }

        private void CreateDefaultParamenter()
        {
            Global.serverIP = OtherUtils.GetServerIP("ipv4");
            Global.port = 44472;

            Global.admistratorPassword = "1234567";

            //Global.n = 5;
            //Global.k = 2;
        }


        private void RefreshScreenContent()
        {
            //txtN.Text = "";
            //txtK.Text = "";

            //txtCurrentN.Text = Global.n.ToString();
            //txtCurrentK.Text = Global.k.ToString();

            txtServerIP.Text = Global.serverIP;
            txtPort.Text = Global.port.ToString();
        }

        private bool SaveSetingsToFile()
        {

            return true;
        }

        private void LoadSettingsFromFile()
        {
            //Global.n = 5;
            //Global.k = 2;
        }

        private void btnReloadAllSystemParameters_Click(object sender, EventArgs e)
        {
            //LoadSettingsFromFile();

            RefreshScreenContent();
        }

        private void btnResetAllSystemParameters_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("Are you sure that you want to reset all settings to default?", "Confirming Dialog", MessageBoxButtons.OKCancel);

            if (dr == DialogResult.OK)
            {
                CreateDefaultParamenter();

                RefreshScreenContent();

                SaveSetingsToFile();
            }
        }

        //private void btnApplyNMSSettingsChange_Click(object sender, EventArgs e)
        //{
        //    try
        //    {
        //        int n = int.Parse(txtCurrentN.Text);
        //        int k = int.Parse(txtCurrentK.Text);

        //        try
        //        {

        //            AuthenManagement authenManagement = AuthenManagement.getInstance();
        //            authenManagement.NMemberSystem = new NMembersSystem(n, k);

        //            Global.n = n;
        //            Global.k = k;

        //            if (SaveSetingsToFile() == true)
        //            {
        //                MessageBox.Show("The change is applied.", "Notice");
        //            }
        //            else
        //            {
        //                MessageBox.Show("Cannot save the settings to file.");
        //            }
        //        }
        //        catch (Exception ex)
        //        {
        //            throw ex;
        //        }
        //    }
        //    catch
        //    {
        //        MessageBox.Show("Perhaps the parameters for NMS are invalid", "Notice");
        //    }
        //}


        //private void btnGenerateNMSKeys_Click(object sender, EventArgs e)
        //{
        //    String nMemStr = txtN.Text;
        //    String kMemStr = txtK.Text;

        //    if (!OtherUtils.IsPositiveNumber(nMemStr) || !OtherUtils.IsPositiveNumber(kMemStr))
        //    {
        //        MessageBox.Show("Incorrect inputs of Number of Clients and Minimum Clients!", "Authentication Error");
        //        return;
        //    }

        //    try
        //    {
        //        int n = int.Parse(nMemStr);
        //        int k = int.Parse(kMemStr);

        //        AuthenManagement.getInstance().NMemberSystem = new NMembersSystem(n, k);

        //        lbWaitingConstructSecret.Text = "Constructing secret. Please wait...";

        //        myNotifyCompletion = new NoParaDelegate(NotifyCompletion);

        //        Thread constructThread = new Thread(doConstructSecret);
        //        constructThread.Priority = ThreadPriority.Normal;
        //        constructThread.IsBackground = true;
        //        constructThread.Start();
        //    }
        //    catch
        //    {
        //        MessageBox.Show("Invalid Input", "Authentication Error");
        //        return;
        //    }
        //}

        private void doConstructSecret()
        {
            //AuthenManagement.getInstance().GenerateInfoForMembers();

            Invoke(myNotifyCompletion);
        }

        public delegate void NoParaDelegate();
        public NoParaDelegate myNotifyCompletion;

        private void NotifyCompletion()
        {
            //lbWaitingConstructSecret.Text = "";

            MessageBox.Show("Construct secret successfully!", "Authentication Notice");
        }

        private void btnStartBroadcasting_Click(object sender, EventArgs e)
        {
            ScreenshotBroadcastWithFeedback.TryToStart();
        }

        private void btnStopBroadcasting_Click(object sender, EventArgs e)
        {
            ScreenshotBroadcastWithFeedback.TryToStop();
        }

        #region N Members System Groupbox
        //private FormSetting formSetting = new FormSetting();
        private void btStartAuthen_Click(object sender, EventArgs e)
        {
            MembersGroup group = TMUtils.LoadGroupInfo(_groups[cbGroup.SelectedIndex].GroupID);
            if (group != null)
            {
                this._authenManager.StartThresholdModel(group);
                this._authenManager.CurrentActiveGroup = group;
                btLogoutGroup.Enabled = true;
                btStartAuthen.Enabled = false;
                lbActiveGroup.Text = group.GroupName;

                lbAuthenType.Text = this._authenManager.AuthenType.ToString();
                rbType1.Enabled = rbType2.Enabled = false;
                cbGroup.Enabled = false;
                gvMemberList.Enabled = false;
                btGroupSetting.Enabled = false;
                //gbLanServer.Enabled = true;
                //gbBluetoothServer.Enabled = true;
            }
            else
            {
                MessageBox.Show("Please Group that you want to login!", "Error");
            }
        }

        private void btGroupSetting_Click(object sender, EventArgs e)
        {
            List<MembersGroup> mgs = new List<MembersGroup>();
            mgs.AddRange(this._groups);
            FormSetting formSetting = new FormSetting();
            formSetting.Groups = mgs;
            formSetting.ShowDialog();

            LoadGroupToCombobox();
            //LoadMembersToDataGridView(_groups[cbGroup.SelectedIndex].GroupID);
        }

        private String curGroupText = "";
        private void cbGroup_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Ask admin password
            gvMemberList.Rows.Clear();
            int idx = cbGroup.SelectedIndex;
            curGroupText = (String)cbGroup.SelectedItem;
            LoadMembersToDataGridView(_groups[idx].GroupID);
        }

        private void LoadGroupToCombobox()
        {
            //String path = OtherUtils.getPath() + @"/Data/Group";
            //string[] files = TMUtils.GetFilesInDirectory(path);
            //if (files != null)
            //    cbGroup.DataSource = files;
            _groups = TMUtils.LoadGroupsName();

            if (_groups != null && _groups.Count != 0)
            {
                List<String> groupsName = new List<string>();
                foreach (MembersGroup group in _groups)
                {
                    groupsName.Add("Group " + group.GroupName);
                }
                cbGroup.DataSource = groupsName;
            }
        }

        private void LoadMembersToDataGridView(int idx)
        {
            List<MemberInfo> mems = TMUtils.LoadGroup(idx);
            gvMemberList.Rows.Add(mems.Count);
            int i = 0;
            foreach (MemberInfo mem in mems)
            {
                DataGridViewRow row = gvMemberList.Rows[i++];
                row.Cells["gvcID"].Value = mem.MemberID;
                row.Cells["gvcName"].Value = mem.Name;
                row.Cells["gvcEmail"].Value = mem.Email;
                row.Cells["gvcRole"].Value = mem.Role;
            }
        }

        private void cbGroup_TextChanged(object sender, EventArgs e)
        {
            //if (!"".Equals(curGroupText))
            //    cbGroup.Text = curGroupText;
        }

        private void btLogoutGroup_Click(object sender, EventArgs e)
        {
            AuthenManagement.RenewInstance();
            this._authenManager = AuthenManagement.getInstance();
            btLogoutGroup.Enabled = false;
            btStartAuthen.Enabled = true;
            lbActiveGroup.Text = "------";
            lbAuthenType.Text = "------";
            rbType1.Enabled = rbType2.Enabled = true;
            cbGroup.Enabled = true;
            gvMemberList.Enabled = true;
            btGroupSetting.Enabled = true;
        }

        private void rbType1_CheckedChanged(object sender, EventArgs e)
        {
            this._authenManager.AuthenType = 1;
            //rbType1.Checked = true;
            //rbType2.Checked = false;
        }

        private void rbType2_CheckedChanged(object sender, EventArgs e)
        {
            this._authenManager.AuthenType = 2;
            //rbType1.Checked = false;
            //rbType2.Checked = true;
        }
        #endregion

        private void btExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btChangeSystemEmail_Click(object sender, EventArgs e)
        {
            FormChangeSystemEmail fcse = new FormChangeSystemEmail();
            fcse.ShowDialog();
        }
    }
}
